<template>
	<view></view>
</template>

<script lang="uts">
	import { calculateDistance, loadCustomIcon, createBitmapFromText, parseLandBoundary, calculatePolygonCenter } from "./index.uts"

	import Bundle from "android.os.Bundle"
	import { AMap, CameraUpdateFactory, MapView } from "com.amap.api.maps"
	import URL from "java.net.URL"
	import Color from "android.graphics.Color"
	import { GroundOverlayOptions, CameraPosition, PolylineOptions, PolygonOptions, Polyline, Polygon, Marker, MarkerOptions, BitmapDescriptorFactory, LatLngBounds, LatLng, UrlTileProvider, TileOverlayOptions } from "com.amap.api.maps.model"
	import { BitmapFactory, Canvas, Paint, Bitmap } from "android.graphics"
	import { View } from "android.view"
	import File from 'java.io.File';
	import Glide from "com.bumptech.glide.Glide";
	import CustomTarget from "com.bumptech.glide.request.target.CustomTarget"
	import Transition from "com.bumptech.glide.request.transition.Transition"
	import Drawable from "android.graphics.drawable.Drawable"

	// 定义 Land 类型
	type Land = {
		name : string,
		area : string,
		id : number,
		land_boundary : string
	};
	// 定义遥感类型
	type LandRemote = {
		remote_url : string,
		remote_point : string
	};

	type LandRemotePoint = {
		xmin : number,
		xmax : number,
		ymin : number,
		ymax : number
	}

	export default {
		name: "zt-uts-gd-map",
		emits: ["landClickEvent"],
		props: {
			"landArray": {
				type: Array<Land>,
				default: () => [] as Array<Land>
			},
			"landRemoteArray": {
				type: Array<LandRemote>,
				default: () => [] as Array<LandRemote>
			},
		},
		/**
		 * 属性变化监听器实现
		 */
		watch: {
			"landArray": {
				handler(newValue : Array<Land>, oldValue : Array<Land>) {
					this.renderLandArray(); // 渲染地块
				},
				immediate: false
			},
			"landRemoteArray": {
				handler(newValue : Array<LandRemote>, oldValue : Array<LandRemote>) {
					this.addRemoteImageLayer();  // 渲染遥感图
				},
				immediate: false
			},

		},
		data() {
			return {
				aMap: null as AMap | null, // 保持 aMap 为可空类型
				points: [] as Array<LatLng>, // 存储勾画地块时的点
				LandPolygons: [] as Array<Polygon>, // 存储所有多边形的实例
				circleList: [] as Array<Marker>, // 存储所有勾画地块时Marker的实例
				isDrawingEnabled: false, // 控制是否允许勾画
				polyline: null as Polyline | null,
				polygon: null as Polygon | null,
				MapViews: null as MapView | null, // 在 data 中声明 MapViews
				polygonMap: new Map<string, Land>(), // 存储多边形ID和land的映射关系
				layerZIndex: new Map<string, number>([
					["tile", 1.0], // 瓦片图层的 ZIndex
					["line", 10.0], // 折线的 ZIndex
					["polygon", 10.0], // 多边形的 ZIndex
					["landRemote", 15.0], // 遥感图层的 ZIndex
				]),
				MarkerLabel: [] as Array<Marker>  // 地块中label实例
			}
		},

		NVLoad() : MapView {
			const maxZoom = 20
			const minZoom = 3
			const mapView = new MapView($androidContext!)
			mapView.onCreate(new Bundle())
			this.aMap = mapView.getMap() as AMap
			this.aMap?.showMapText(false);  // 隐藏文字标记
			this.aMap?.setMaxZoomLevel(maxZoom.toFloat()) // 设置最大层级
			this.aMap?.setMinZoomLevel(minZoom.toFloat()) // 设置最小层级
			this.addTileOverlays()


			// 禁用比例尺和隐藏logo
			this.aMap?.getUiSettings().setZoomControlsEnabled(false); // 禁用缩放
			this.aMap?.getUiSettings().setLogoBottomMargin(-100); // 隐藏logo

			this.aMap?.setOnMapClickListener(latLng => {
				this.onMapClick(latLng) // 勾画地块

				this.landClick(latLng)  // 地块点击事件
			})

			this.aMap?.setOnCameraChangeListener(new MyOnCameraChangeListener(
				(zoomLevel : number) => {
					let flag = zoomLevel <= 15 ? false : true
					this.MarkerLabel.forEach((marker : Marker) => {
						marker.setVisible(flag)
					})
				}
			))

			this.MapViews = mapView // 赋值给 MapViews
			return mapView // 确保返回 mapView
		},

		NVBeforeUnload() : void {
			// 使用严格的 null 检查
			const MapViews = this.MapViews
			if (MapViews !== null) { // 检查 MapViews 是否为 null
				MapViews.onDestroy()
				this.MapViews = null
			}
		},

		methods: {
			getZIndex(key : string, defaultValue : number = 0.0) : Float {
				const value = this.layerZIndex.get(key) ?? defaultValue // 获取值
				return (value as number).toFloat() // 转换为 Float
			},

			addTileOverlays() {

				// 创建 TileProvider 实例
				const tileProvider = new MyUrlTileProvider(256, 256);

				// 设置 TileOverlayOptions
				const tileOverlayOptions = new TileOverlayOptions().tileProvider(tileProvider);

				// 添加瓦片图层并设置 ZIndex
				this.aMap?.addTileOverlay(tileOverlayOptions).setZIndex(this.getZIndex("tile"));
			},
			landClick(latLng : LatLng) {
				const polygon = this.isPointInPolygon(latLng)
				if (polygon != null) {
					const land = this.polygonMap.get(polygon.getId());
					if (land != null) {  // 确保 land 不为 null
						this.$emit("landClickEvent", land);
					}
				}
			},
			isPointInPolygon(point : LatLng) : Polygon | null {
				// 使用 `find` 方法在 `LandPolygons` 中查找包含该点的多边形
				const foundPolygon = this.LandPolygons.find((polygon : Polygon) : boolean => polygon.contains(point));

				// 直接返回 `foundPolygon`，find 方法已经处理了 null 的情况
				return foundPolygon;
			},
			startDrawing() {
				const zoom = 12
				this.isDrawingEnabled = true // 启用勾画
				this.points = [] // 重置点
				this.circleList = [] // 重置圆圈列表
				this.aMap?.getUiSettings().setScrollGesturesEnabled(false) // 禁用双击放大
				if (this.points.length > 0) {
					this.aMap?.moveCamera(CameraUpdateFactory.newLatLngZoom(this.points[0], zoom.toFloat())) // 设置默认层级为12
				}
			},

			onMapClick(latLng : LatLng) {
				if (!this.isDrawingEnabled) return // 禁止在闭合状态下勾画或未启用勾画

				this.points.push(latLng) // 添加点击的点
				this.addMarker(latLng) // 显示点击的点
				this.drawLine() // 绘制连接点的线
			},

			addMarker(latLng : LatLng) {
				const anchor = 0.5
				const iconBitmap = loadCustomIcon("uni_modules/zt-uts-gd-map/static/circle.png") // 加载自定义图标

				const marker = this.aMap?.addMarker(new MarkerOptions()
					.position(latLng)
					.icon(iconBitmap)
					.anchor(anchor.toFloat(), anchor.toFloat())
				)
				if (marker != null) {
					this.circleList.push(marker) // 保存标记
				}
			},

			closeDrawing() {
				this.aMap?.getUiSettings().setScrollGesturesEnabled(true) // 恢复双击放大
				this.isDrawingEnabled = false
				this.clearAllOverlays() // 清除覆盖物
			},

			clearAllOverlays() {
				this.polyline?.remove() // 移除折线
				this.polygon?.remove() // 移除多边形
				this.circleList.forEach(marker => marker.remove()) // 移除所有标记
				this.circleList = [] // 清空标记列表
				this.points = [] // 清空点列表
			},

			drawLine() {
				this.polyline?.remove() // 移除现有的折线
				const a : number = 7

				if (this.points.length > 1) {
					const latLngs = [...this.points] // 将 points 转换为 LatLng 数组
					this.polyline = this.aMap?.addPolyline(new PolylineOptions()
						.addAll(latLngs)
						.width(a.toFloat())
						.color(Color.parseColor("#ffa502"))
						.zIndex(this.getZIndex("line"))
					) // 绘制折线
				}

				this.checkPolygonClosure() // 检查多边形是否闭合
			},

			checkPolygonClosure() {
				if (this.points.length > 2) {
					const distance = calculateDistance(this.points[0], this.points[this.points.length - 1])
					if (distance < 500) { // 距离小于500米, 自动闭合
						this.isDrawingEnabled = false
						this.drawPolygon() // 绘制多边形
						this.enableDragging()  // 启用拖拽
						this.polyline?.remove() // 移除现有的折线
					}
				}
			},

			drawPolygon() {
				this.polygon?.remove() // 移除现有的多边形

				if (this.points.length > 2) {
					const latLngs = [...this.points] // 将 points 转换为 LatLng 数组
					this.polygon = this.aMap?.addPolygon(new PolygonOptions()
						.addAll(latLngs)
						.strokeColor(Color.parseColor("#ffa502"))
						.fillColor(Color.parseColor("#eccc68")) // 设置填充颜色为可见色
						.zIndex(this.getZIndex("polygon")) // 使用辅助函数获取 ZIndex
					) // 绘制多边形
				}
			},

			undoPoint() {
				if (this.points.length > 0) {
					const lastPoint = this.points.pop() // 移除最后一个点
					// 使用 findIndex 查找对应的 Marker
					const markerIndex = this.circleList.findIndex((marker : Marker) : boolean => {
						const position = marker.getPosition()
						return position == lastPoint
					})
					if (markerIndex != -1) {
						this.circleList[markerIndex].remove() // 移除对应的 Marker
						this.circleList.splice(markerIndex, 1) // 从列表中移除
					}
					if (!this.isDrawingEnabled) {
						this.polyline?.remove() // 移除折线
						this.polygon?.remove() // 移除多边形
						this.circleList.forEach((marker : Marker) => {
							marker.setDraggable(false) // 取消每个 Marker 可拖拽
						})
						this.isDrawingEnabled = true
					}
					this.drawLine() // 更新线
				}
			},

			savePolygon(callback : (points : Array<LatLng>) => void) { // 接收回调函数
				if (!this.isDrawingEnabled) {
					callback(this.points) // 调用回调函数并传递 points
				}
			},

			enableDragging() {
				this.circleList.forEach((marker : Marker) => {
					marker.setDraggable(true) // 设置每个 Marker 可拖拽
				})

				this.aMap?.setOnMarkerDragListener(new MyMarkerDragListener(
					(newPosition : LatLng, index : number) => {
						this.updatePoints(newPosition, index) // 直接传递新位置
					},
					this.circleList
				))
			},

			updatePoints(newPosition : LatLng, index : number) {
				this.points[index] = newPosition // 更新点的位置
				this.drawPolygon() // 更新多边形
			},

			/**
			* 渲染 landArray 数据到地图
			 */
			renderLandArray() {
				const strokeWidth = 10
				this.landArray.forEach((land : Land) => {
					const name = land.name
					const area = land.area
					const land_boundary = land.land_boundary; // 获取边界字符串

					const label = `${name}||${area}亩`;
					const points = parseLandBoundary(land_boundary);
					// 添加多边形
					const polygon = this.aMap?.addPolygon(new PolygonOptions()
						.addAll(points)
						.strokeWidth(strokeWidth.toFloat())
						.strokeColor(Color.parseColor("#ffa502"))
						.fillColor(Color.parseColor("#eccc68"))
						.zIndex(this.getZIndex("polygon"))
					);
					if (polygon != null) {
						const polygonId = polygon.getId(); // 获取多边形ID
						this.LandPolygons.push(polygon); // 保存多边形实例
						this.polygonMap.set(polygonId, land); // 将多边形ID和 land 绑定
					}
					const center = calculatePolygonCenter(points)
					this.addLabel(center, label) // 添加标签
				});
				this.fitMapToPolygons()
			},

			addLabel(position : LatLng, label : string) {
				const anchor = 0.5
				const bitmap = createBitmapFromText(label) // 创建文本位图
				const markerOptions = new MarkerOptions()
					.position(position)
					.icon(BitmapDescriptorFactory.fromBitmap(bitmap)) // 使用文本位图
					.anchor(anchor.toFloat(), anchor.toFloat()) // 设置锚点为中心

				const marker = this.aMap?.addMarker(markerOptions)
				if (marker != null) {
					this.MarkerLabel.push(marker)
				}
			},

			fitMapToPolygons() {
				// 创建一个 LatLngBounds.Builder 对象，用于构建矩形边界
				const boundsBuilder = new LatLngBounds.Builder();

				// 遍历所有的多边形，获取它们的顶点坐标并添加到边界构建器中
				this.LandPolygons.forEach((polygon : Polygon) => {
					const points = polygon.getPoints(); // 获取每个多边形的顶点
					points.forEach((point : LatLng) => {
						boundsBuilder.include(point); // 将点添加到 LatLngBounds.Builder 中
					});
				});

				// 生成包含所有顶点的 LatLngBounds 对象
				const bounds = boundsBuilder.build();

				// 调整地图的视角到包含所有多边形的矩形边界，并自动调整缩放层级

				this.aMap?.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 100)); // 第二个参数为边距
			},

			addRemoteImageLayer() {
				this.landRemoteArray.forEach((item : LandRemote) => {
					const remoteUrl = item.remote_url
					const remotePoint = JSON.parse<LandRemotePoint>(item.remote_point) as LandRemotePoint
					// 创建 LatLngBounds 对象

					const bounds = new LatLngBounds(
						new LatLng(remotePoint.ymin.toDouble(), remotePoint.xmin.toDouble()),
						new LatLng(remotePoint.ymax.toDouble(), remotePoint.xmax.toDouble())
					)

					// 加载图像并创建 BitmapDescriptor
					this.loadImage(remoteUrl, bounds)
				})
			},
			// 加载图片并添加到地图
			loadImage(url : string, bounds : LatLngBounds) {
				const imageLoader = new ImageLoader($androidContext!);
				imageLoader.loadImage(url, (bitmap) => {
					this.addBitmapToMap(bitmap, bounds);
				});
			},
			// 示例方法：将 Bitmap 添加到地图
			addBitmapToMap(bitmap : Bitmap, bounds : LatLngBounds) {
				const groundOverlayOptions = new GroundOverlayOptions()
					.image(BitmapDescriptorFactory.fromBitmap(bitmap))
					.positionFromBounds(bounds) // 设置图像的位置
					.zIndex(this.getZIndex("landRemote"));

				this.aMap?.addGroundOverlay(groundOverlayOptions); // 添加到地图
			}
		}
	}

	class MyOnCameraChangeListener implements AMap.OnCameraChangeListener {

		private callback : (zoomLevel : number) => void

		constructor(callback : (zoomLevel : number) => void) {
			this.callback = callback
		}

		override onCameraChange(positon : CameraPosition) {
			this.callback(positon.zoom)
		}

		override onCameraChangeFinish(position : CameraPosition) {

		}

	}


	class MyMarkerDragListener implements AMap.OnMarkerDragListener {

		private onUpdatePoints : (newPosition : LatLng, index : number) => void
		private markers : Array<Marker> = []

		private drawIndex : number = -1


		constructor(onUpdatePoints : (newPosition : LatLng, index : number) => void, markers : Array<Marker>) {
			this.onUpdatePoints = onUpdatePoints
			this.markers = markers
		}

		override onMarkerDragStart(marker : Marker) {
			this.drawIndex = this.markers.findIndex((item : Marker) : boolean => {
				return marker.getId() == item.getId()
			})
		}

		override onMarkerDrag(marker : Marker) {
			const newPosition = marker.getPosition()
			this.onUpdatePoints(newPosition, this.drawIndex) // 传递新位置
		}

		override onMarkerDragEnd(marker : Marker) {

		}
	}

	class MyUrlTileProvider extends UrlTileProvider {
		constructor(tileWidth : number, tileHeight : number) {
			super(tileWidth.toInt(), tileHeight.toInt());
		}

		override getTileUrl(x : Int, y : Int, zoom : Int) : URL {
			// 返回瓦片的 URL
			const url : string = `http://t0.tianditu.gov.cn/img_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX=${zoom}&TILEROW=${y}&TILECOL=${x}&tk=38d3a9e8f0f661bc3be7d63256c255ca`;

			return new URL(url);
		}

	}
</script>

<style>
</style>